package com.jsptags.navigation.pager.parser;

@SuppressWarnings("serial")
public class ParseException extends Exception {

	protected boolean specialConstructor;
	public Token currentToken;
	public int expectedTokenSequences[][];
	public String tokenImage[];
	protected String eol;

	public String getMessage() {
		if (!specialConstructor)
			return super.getMessage();
		String s = "";
		int i = 0;
		for (int j = 0; j < expectedTokenSequences.length; j++) {
			if (i < expectedTokenSequences[j].length)
				i = expectedTokenSequences[j].length;
			for (int k = 0; k < expectedTokenSequences[j].length; k++)
				s = new StringBuffer().append(s)
						.append(tokenImage[expectedTokenSequences[j][k]])
						.append(' ').toString();

			if (expectedTokenSequences[j][expectedTokenSequences[j].length - 1] != 0)
				s = new StringBuffer().append(s).append("...").toString();
			s = new StringBuffer().append(s).append(eol).append("    ")
					.toString();
		}

		String s1 = "Encountered \"";
		Token token = currentToken.next;
		for (int l = 0; l < i; l++) {
			if (l != 0)
				s1 = new StringBuffer().append(s1).append(' ').toString();
			if (token.kind == 0) {
				s1 = new StringBuffer().append(s1).append(tokenImage[0])
						.toString();
				break;
			}
			s1 = new StringBuffer().append(s1).append(add_escapes(token.image))
					.toString();
			token = token.next;
		}

		s1 = new StringBuffer().append(s1).append("\" at line ")
				.append(currentToken.next.beginLine).append(", column ")
				.append(currentToken.next.beginColumn).toString();
		s1 = new StringBuffer().append(s1).append('.').append(eol).toString();
		if (expectedTokenSequences.length == 1)
			s1 = new StringBuffer().append(s1).append("Was expecting:")
					.append(eol).append("    ").toString();
		else
			s1 = new StringBuffer().append(s1).append("Was expecting one of:")
					.append(eol).append("    ").toString();
		s1 = new StringBuffer().append(s1).append(s).toString();
		return s1;
	}

	protected String add_escapes(String s) {
		StringBuffer stringbuffer = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c;
			switch (s.charAt(i)) {
			case 0: // '\0'
				break;

			case 8: // '\b'
				stringbuffer.append("\\b");
				break;

			case 9: // '\t'
				stringbuffer.append("\\t");
				break;

			case 10: // '\n'
				stringbuffer.append("\\n");
				break;

			case 12: // '\f'
				stringbuffer.append("\\f");
				break;

			case 13: // '\r'
				stringbuffer.append("\\r");
				break;

			case 34: // '"'
				stringbuffer.append("\\\"");
				break;

			case 39: // '\''
				stringbuffer.append("\\'");
				break;

			case 92: // '\\'
				stringbuffer.append("\\\\");
				break;

			default:
				if ((c = s.charAt(i)) < ' ' || c > '~') {
					String s1 = "0000" + Integer.toString(c, 16);
					stringbuffer.append("\\u"
							+ s1.substring(s1.length() - 4, s1.length()));
				} else {
					stringbuffer.append(c);
				}
				break;
			}
		}

		return stringbuffer.toString();
	}

	public ParseException(Token token, int ai[][], String as[]) {
		super("");
		eol = System.getProperty("line.separator", "\n");
		specialConstructor = true;
		currentToken = token;
		expectedTokenSequences = ai;
		tokenImage = as;
	}

	public ParseException() {
		eol = System.getProperty("line.separator", "\n");
		specialConstructor = false;
	}

	public ParseException(String s) {
		super(s);
		eol = System.getProperty("line.separator", "\n");
		specialConstructor = false;
	}
}
